﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.IO;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using PAT.Entities;
using PAT.Services;
using PAT.Data.Bases;

public partial class ascx_Menu : System.Web.UI.UserControl
{
    #region Atributos

    /// <summary>
    /// Objeto con la información del usuario logueado
    /// </summary>
    private PatUsuario usuario = new PatUsuario();

    /// <summary>
    /// Servicio para obtener la información de las opciones del menú asociadas a un rol
    /// </summary>
    private PatRolMenuService rolMenuService = new PatRolMenuService();
    
    /// <summary>
    /// Servicio para obtener el menú
    /// </summary>
    private PatMenuService menuService = new PatMenuService();
    
    /// <summary>
    /// Identificador del rol del usuario logueado
    /// </summary>
    private int idRol;

    /// <summary>
    /// Propiedad para acceder al atributo <paramref name="idRol"/>
    /// </summary>
    public int IdRol { set { idRol = value; } get { return idRol; } }

    #endregion

    #region Eventos

    /// <summary>
    /// Evento que se dispara en la carga del control de usuario
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e)
    {
        ((IMaster)Page.Master).RecuperarRol += new RecuperarRolEventHandler(RecuperarRolSeleccionado);
        if (Session["menu"] != null)
            ConstruirMenu((DataTable)Session["menu"]);
        else
        {
            usuario = RecuperarUsuarioLogueado();
            ConstruirMenu(RecuperarOpcionesMenuXRol(IdRol).Tables[0]);
        }
    }

    /// <summary>
    /// Manejador del evento RecuperarRol de la MasterPage
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public void RecuperarRolSeleccionado(object sender, RecuperarRolEventArgs e)
    {
        this.IdRol = e.IdRol;
        usuario = RecuperarUsuarioLogueado();
        ConstruirMenu(RecuperarOpcionesMenuXRol(IdRol).Tables[0]);
    }

    #endregion

    #region Métodos

    /// <summary>
    /// Se obtiene el usuario logueado de la Session
    /// </summary>
    /// <returns>Objeto con la información del usuario</returns>
    private PatUsuario RecuperarUsuarioLogueado()
    {
        return (PatUsuario)Session["usuario"];
    }

    /// <summary>
    /// Obtiene la información de las opciones del menú asociadas al rol
    /// </summary>
    /// <param name="idRol">Identificador del rol</param>
    /// <returns>Objeto con la información de las opciones del menú</returns>
    private DataSet RecuperarOpcionesMenuXRol(int idRol)
    {
        DataSet resultados = new DataSet();
        try
        {
            menuService = new PatMenuService();
            resultados = menuService.GetMenuByUsuarioRol(usuario.IdUsuario, idRol);
            if (resultados.Tables[0].Rows.Count != 0)
                Session["menu"] = resultados.Tables[0];
        }
        catch (Exception ex)
        {
            throw ex;
        }
        return resultados;
    }

    /// <summary>
    /// Construye el menú en el control TabPanel dependiendo de las opciones que se envian como parámetro
    /// </summary>
    /// <param name="opciones">Objeto con la opciones del menú</param>
    private void ConstruirMenu(DataTable opciones)
    {
        if (opciones.Rows.Count != 0)
        {
            foreach (DataRow item in opciones.Rows)
            {
                if (Convert.IsDBNull(item["ID_MENU_PADRE"]))
                {
                    AjaxControlToolkit.TabPanel tabPadre = new AjaxControlToolkit.TabPanel();
                    tabPadre.ID = "tab_" + item["ID_MENU"].ToString();
                    tabPadre.Visible = true;
                    tabPadre.HeaderText = item["DESCRIPCION"].ToString();
                    tabPadre.ContentTemplate = new TabPanelTemplate(ConstruirHijos(Convert.ToInt32(item["ID_MENU"]), opciones));
                    tabMenu.Tabs.Add(tabPadre);
                }
            }
            tabMenu.ActiveTabIndex = 0;
            tabMenu.Visible = true;
        }
    }

    /// <summary>
    /// Construye las opciones hijas de un elemento del menú
    /// </summary>
    /// <param name="idPadre">Identificador de la opción padre</param>
    /// <param name="opciones">Objeto con las opciones del menú</param>
    /// <returns></returns>
    private string ConstruirHijos(int idPadre, DataTable opciones)
    {
        string html = string.Empty;
        StringBuilder htmlBuilder = new StringBuilder();
        DataRow[] hijos = opciones.Select("ID_MENU_PADRE=" + idPadre.ToString() + "");
        int totalOpciones = 0;
        int cantidadOpcionesPanel = 0;
        int totalOpcionesPanel = int.Parse(ConfigurationManager.AppSettings["numeroOpcionesPanelMenu"]);
        int opcionesSobrantes = 0;
        int opcionesPintadas = 0;
        if (hijos != null)
        {
            if (hijos.Length != 0)
            {
                totalOpciones = hijos.Length;
                cantidadOpcionesPanel = totalOpciones / totalOpcionesPanel;
                opcionesSobrantes = totalOpciones % totalOpcionesPanel;
                htmlBuilder.Append("<div id=\"topics\">");
                for (int i = 0; i < cantidadOpcionesPanel; i++)
                {
                    htmlBuilder.Append("<div class=\"thirds\">");
                    htmlBuilder.Append("<ul>");
                    for (int j = 0; j < totalOpcionesPanel; j++)
                    {
                        htmlBuilder.Append("<li>");
                        htmlBuilder.Append("<a href=\"" + hijos[opcionesPintadas]["URL"].ToString() + "\">" + hijos[opcionesPintadas]["DESCRIPCION"].ToString() + "</a>");
                        htmlBuilder.Append("</li>");
                        opcionesPintadas++;
                    }
                    htmlBuilder.Append("</ul>");
                    htmlBuilder.Append("</div>");
                }
                if (opcionesSobrantes != 0)
                {
                    htmlBuilder.Append("<div class=\"thirds\">");
                    htmlBuilder.Append("<ul>");
                    for (int i = 0; i < opcionesSobrantes; i++)
                    {
                        htmlBuilder.Append("<li>");
                        htmlBuilder.Append("<a href=\"" + hijos[opcionesPintadas]["URL"].ToString() + "\">" + hijos[opcionesPintadas]["DESCRIPCION"].ToString() + "</a>");
                        htmlBuilder.Append("</li>");
                        opcionesPintadas++;
                    }
                    htmlBuilder.Append("</ul>");
                    htmlBuilder.Append("</div>");
                }
                htmlBuilder.Append("</div>");
            }
        }
        html = htmlBuilder.ToString();
        return html;
    }

    #endregion
    
}

/// <summary>
/// Clase que permite extender el TabPanel para construir una plantilla personalizada
/// </summary>
public class TabPanelTemplate : ITemplate
{
    #region Atributos

    /// <summary>
    /// Cadena que representa el contenido que se agregar a la plantilla
    /// </summary>
    private string contenido = string.Empty;

    #endregion

    #region Métodos

    /// <summary>
    /// Cosntructor que recibe el contenido de la plantilla
    /// </summary>
    /// <param name="contenido">Cadena con el contenido que se desea plasmar en la plantilla</param>
    public TabPanelTemplate(string contenido)
    {
        this.contenido = contenido;
    }

    /// <summary>
    /// Método que asocia la interface ITemplate con el contenido definido
    /// </summary>
    /// <param name="container"></param>
    public void InstantiateIn(Control container)
    {
        container.Controls.Add(new LiteralControl(contenido));
    }

    #endregion

    
}